home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / osrc.arc / PC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-26  |  8.3 KB  |  403 lines

  1. /* OS- and machine-dependent stuff for IBM-PC running MS-DOS and Turbo-C */
  2. #include <stdio.h>
  3. #include <dir.h>
  4. #include <dos.h>
  5. #include <sys/stat.h>
  6. #include <string.h>
  7. #include <process.h>
  8. #include <fcntl.h>
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "internet.h"
  12. #include "iface.h"
  13. #include "cmdparse.h"
  14.  
  15. unsigned _stklen = 8192;
  16. void interrupt btick();
  17. void interrupt nullvec();
  18. unsigned grabcore();
  19. char *getenv();
  20.  
  21.  
  22. /* This flag is set by setirq() if IRQ 8-15 is used, indicating
  23.  * that the machine is a PC/AT with a second 8259 interrupt controller.
  24.  * If this flag is set, the interrupt return code in pcgen.asm will
  25.  * send an End of Interrupt command to the second 8259 as well as the
  26.  * first.
  27.  */
  28. char Isat;
  29.  
  30. /* Interface list header */
  31. struct iface *Ifaces;
  32.  
  33. char Ttbuf[BUFSIZ];
  34. int saved_break;
  35.  
  36. /* Keyboard input buffer */
  37. #define    KBSIZE    256
  38. struct {
  39.     char buf[KBSIZE];
  40.     char *wp;
  41.     char *rp;
  42.     int cnt;
  43. } Keyboard;
  44.  
  45. errhandler(errval,ax,bp,si)
  46. int errval,ax,bp,si;
  47. {
  48.     return 3;    /* Fail the system call */
  49. }
  50.  
  51. /* Called at startup time to set up console I/O, memory heap */
  52. ioinit(mem)
  53. int32 mem;
  54. {
  55. #ifndef __TURBOC__
  56.     struct sgttyb ttybuf;
  57. #endif
  58.     /* Ignore ctrl-breaks */
  59.     setvect(0x23,nullvec);
  60.  
  61.     /* Fail all I/O errors */
  62.     harderr(errhandler);
  63.  
  64.     /* Save these two file table entries for something more useful */
  65.     fclose(stdaux);
  66. #ifdef __TURBOC__
  67.     fclose(stdprn);
  68. #else
  69.     fclose(stdprt);
  70. #endif
  71.  
  72.     /* Interrupts use a special stack deep in data space.
  73.      * Calls to sbrk() (invoked by malloc when it needs more memory
  74.      * from the system) at interrupt time will fail because sbrk()
  75.      * will think that the stack has overwritten the heap. So
  76.      * grab all the memory we can now for the heap so that malloc
  77.      * won't have to call sbrk and alloc_mbuf() won't fail unnecessarily
  78.      * at interrupt time.
  79.      */
  80. #ifdef    LARGEDATA
  81.     grabcore(mem);
  82. #else
  83.     grabcore(mem);
  84. #endif
  85.  
  86.     setbuf(stdout,Ttbuf);
  87. #ifdef __TURBOC__
  88.     saved_break = getcbrk();
  89.     setcbrk(0);
  90.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20);  /* put stdout in raw mode */
  91. #else
  92.     /* Put display in raw mode. Note that this breaks tab expansion,
  93.      * so you need to run NANSI.SYS or equivalent.
  94.      */
  95.     ioctl(1,TIOCGETP,&ttybuf);
  96.     ttybuf.sg_flags = RAW;
  97.     ioctl(1,TIOCSETP,&ttybuf);
  98. #endif
  99.     /* Link timer handler into timer interrupt chain */
  100.     chtimer(btick);
  101.  
  102.     /* Find out what multitasker we're running under, if any */
  103.     chktasker();
  104.  
  105.     /* Initialize keyboard queue */
  106.     Keyboard.rp = Keyboard.wp = Keyboard.buf;
  107.  
  108. }
  109. /* Called just before exiting to restore console state */
  110. iostop()
  111. {
  112. #ifndef __TURBOC__
  113.     struct sgttyb ttybuf;
  114. #endif
  115.  
  116.     setbuf(stdout,NULLCHAR);
  117. #ifdef __TURBOC__
  118.     setcbrk(saved_break);
  119.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20);  /* put stdout in cooked mode */
  120. #else
  121.     ioctl(1,TIOCGETP,&ttybuf);
  122.     ttybuf.sg_flags &= ~RAW;
  123.     ioctl(1,TIOCSETP,&ttybuf);
  124. #endif
  125.     while(Ifaces != NULLIF){
  126.         if(Ifaces->stop != NULLFP)
  127.             (*Ifaces->stop)(Ifaces);
  128.         Ifaces = Ifaces->next;
  129.     }
  130.     /* Unlink timer handler from timer chain */
  131.     uchtimer();
  132. }
  133. /* Spawn subshell */
  134. doshell(argc,argv)
  135. int argc;
  136. char *argv[];
  137. {
  138.     char *command,*getenv();
  139.     int ret;
  140. #ifdef __TURBOC__
  141.  
  142.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20);  /* put stdout in cooked mode */
  143.     if((command = getenv("COMSPEC")) == NULLCHAR)
  144.         command = "/COMMAND.COM";
  145.     ret = spawnv(P_WAIT,command,argv);
  146.  
  147.     ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20);  /* put stdout in raw mode */
  148.     return ret;
  149. #else
  150.     struct sgttyb ttybuf,ttysav;
  151.  
  152.     ioctl(1,TIOCGETP,&ttysav);
  153.     ioctl(1,TIOCGETP,&ttybuf);
  154.     ttybuf.sg_flags &= ~RAW;
  155.     ioctl(1,TIOCSETP,&ttybuf);
  156.  
  157.     if((command = getenv("COMSPEC")) == NULLCHAR)
  158.         command = "/COMMAND.COM";
  159.     ret = fexecl(command,command,NULLCHAR);
  160.     ioctl(1,TIOCSETP,&ttysav);
  161.     if(ret == -1)
  162.         return -1;
  163.     else
  164.         return wait();
  165. #endif
  166. }
  167.  
  168. /* Keyboard interrupt handler */
  169. void
  170. kbint()
  171. {
  172.     int sig = 0;
  173.     int c;
  174.  
  175.     while((c = kbraw()) != -1 && Keyboard.cnt < KBSIZE){
  176.         sig = 1;
  177.         *Keyboard.wp++ = c;
  178.         if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  179.             Keyboard.wp = Keyboard.buf;
  180.         Keyboard.cnt++;
  181.     }
  182.     if(sig){
  183.         psignal(&Keyboard,1);
  184.     }
  185. }
  186. static int
  187. kbchar()
  188. {
  189.     char i_state;
  190.     char c;
  191.  
  192.     i_state = dirps();
  193.     while(Keyboard.cnt == 0)
  194.         pwait(&Keyboard);
  195.     c = *Keyboard.rp++;
  196.     if(Keyboard.rp == &Keyboard.buf[KBSIZE])
  197.         Keyboard.rp = Keyboard.buf;
  198.     Keyboard.cnt--;
  199.     restore(i_state);
  200.     return c;
  201. }
  202. /* Read characters from the keyboard, translating them to "real" ASCII.
  203.  * If none are ready, block. The F-10 key is special; translate it to -2.
  204.  */
  205. int
  206. kbread()
  207. {
  208.     int c;
  209.  
  210.     if((c = kbchar()) == 0){
  211.         /* Lead-in to a special char */
  212.         c = kbchar();
  213.         switch(c){
  214.         case 3:        /* NULL (bizzare!) */
  215.             c = 0;
  216.             break;
  217.         case 68:    /* F-10 key (used as command-mode escape) */
  218.             c = -2;
  219.             break;
  220.         case 83:    /* DEL key */
  221.             c = 0x7f;
  222.             break;
  223.         default:    /* Dunno what it is */
  224.             c = -1;
  225.         }
  226.     }
  227.     return c;
  228. }
  229. #define    CTLZ    26
  230. /* Special version of aputc() (used by putchar and printf) that filters
  231.  * out nasty characters that screw up the DDOS and ANSI terminal drivers
  232.  */
  233. aputc(c,file)
  234. char c;
  235. FILE *file;
  236. {
  237.     /* Nulls get displayed as spaces by ansi.sys (wrong)
  238.      * ^Z's seem to hang the DoubleDos and DesqView screen drivers
  239.      */
  240.     if((c == '\0' || c == CTLZ) && file == stdout)
  241.         return c;
  242.     /* Do end-of-line translations */
  243.     if(c == '\n')
  244.         putc('\r',file);
  245.     return putc(c,file);
  246. }
  247.  
  248. /* Called from the timer routine on each tick */
  249. systick()
  250. {
  251.     /* Tickle the keyboard interrupt. This nonsense is
  252.      * necessary because there's no way to get a hardware interrupt
  253.      * from the BIOS.
  254.      */
  255.     kbint();
  256.  
  257.     /* Flush out console. This gains efficiency in telnet
  258.      * since it only handles a character at a time, at the cost
  259.      * of a slight echo delay.
  260.      */
  261.     fflush(stdout);
  262. }
  263. /* Reset the CPU, reboot DOS */
  264. sysreset()
  265. {
  266. }
  267.  
  268. /* Install hardware interrupt handler.
  269.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  270.  * Note that bus line IRQ2 maps to IRQ9 on the AT
  271.  */
  272. setirq(irq,handler)
  273. unsigned irq;
  274. void interrupt (*handler)();
  275. {
  276.     /* Set interrupt vector */
  277.     if(irq < 8){
  278.         setvect(8+irq,handler);
  279.     } else if(irq < 16){
  280.         Isat = 1;
  281.         setvect(0x70 + irq - 8,handler);
  282.     } else {
  283.         return -1;
  284.     }
  285.     return 0;
  286. }
  287. /* Return pointer to hardware interrupt handler.
  288.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  289.  */
  290. void interrupt
  291. (*getirq(irq))()
  292. unsigned int irq;
  293. {
  294.     /* Set interrupt vector */
  295.     if(irq < 8){
  296.         return getvect(8+irq);
  297.     } else if(irq < 16){
  298.         return getvect(0x70 + irq - 8);
  299.     } else {
  300.         return NULLVIFP;
  301.     }
  302. }
  303. /* Disable hardware interrupt */
  304. maskoff(irq)
  305. unsigned irq;
  306. {
  307.     if(irq < 8){
  308.         setbit(0x21,(char)(1<<irq));
  309.     } else if(irq < 16){
  310.         irq -= 8;
  311.         setbit(0xa1,(char)(1<<irq));
  312.     } else {
  313.         return -1;
  314.     }
  315.     return 0;
  316. }
  317. /* Enable hardware interrupt */
  318. maskon(irq)
  319. unsigned irq;
  320. {
  321.     if(irq < 8){
  322.         clrbit(0x21,(char)(1<<irq));
  323.     } else if(irq < 16){
  324.         irq -= 8;
  325.         clrbit(0xa1,(char)(1<<irq));
  326.     } else {
  327.         return -1;
  328.     }
  329.     return 0;
  330. }
  331. /* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
  332. getmask(irq)
  333. unsigned irq;
  334. {
  335.     if(irq < 8)
  336.         return (inportb(0x21) & (1 << irq)) ? 0 : 1;
  337.     else if(irq < 16){
  338.         irq -= 8;
  339.         return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
  340.     } else
  341.         return -1;
  342. }
  343. /* Called from assembler stub linked to BIOS interrupt 1C, called on each
  344.  * hardware clock tick. Signal a clock tick to the timer process.
  345.  */
  346. int Tick;
  347. ctick()
  348. {
  349.     Tick++;
  350.     psignal(&Tick,1);
  351. }
  352. /* Set bit(s) in I/O port */
  353.  
  354. setbit(port,bits)
  355. unsigned port;
  356. char bits;
  357. {
  358.     outportb(port,(char)inportb(port)|bits);
  359. }
  360. /* Clear bit(s) in I/O port */
  361. clrbit(port,bits)
  362. unsigned port;
  363. char bits;
  364. {
  365.     outportb(port,(char)(inportb(port) & ~bits));
  366. }
  367. /* Convert a pointer to a long integer */
  368. long
  369. ptol(p)
  370. void *p;
  371. {
  372.     long x;
  373.  
  374.     x = FP_OFF(p);
  375. #ifdef    LARGEDATA
  376.     x |= (long)FP_SEG(p) << 16;
  377. #endif
  378.     return x;
  379. }
  380. /* Convert a huge pointer to a long integer */
  381. long
  382. hptol(p)
  383. void huge *p;
  384. {
  385.     long x;
  386.  
  387.     x = FP_OFF(p);
  388.     x += (long)FP_SEG(p) << 4;
  389.     return x;
  390. }
  391. void *
  392. ltop(l)
  393. long l;
  394. {
  395.     register unsigned seg,offset;
  396.  
  397.     seg = l >> 16;
  398.     offset = l;
  399.     return MK_FP(seg,offset);
  400. }
  401.  
  402.  
  403.